<?php
class EWebby_UI_Widgets_WidgetDocument {
	private $_document;
	private $_widget;
		
    public function __construct($widget) {		
		$this->_document = new DomDocument();		        
		$this->_document->formatOutput = EWebby_UI_Page::$formatOutput;
		$this->_document->preserveWhiteSpace = EWebby_UI_Page::$preserveWhiteSpace;
		
		$this->_widget = $widget;
    }
    
    public static function getInnerHTML($node) {
    	$tmp_doc = new DOMDocument();
		$tmp_doc->formatOutput = EWebby_UI_Page::$formatOutput;
		$tmp_doc->preserveWhiteSpace = EWebby_UI_Page::$preserveWhiteSpace;
		if( isset($node->childNodes) ) {
			foreach ($node->childNodes as $child) {
				$tmp_doc->appendChild($tmp_doc->importNode($child, true));
			}
		} else {
			$tmp_doc->appendChild($tmp_doc->importNode($node, true));
		}
		
		return $tmp_doc->saveHTML();
    }

    public static function createDocument($content) {
    	$document = new EWebby_UI_Widgets_WidgetDocument(null);
    	$document->load($content);
    	
    	return $document;
    }
    public function load($content, $loadChilds=true) {
		if( @$this->_document->loadHTML($content) ) {
			if( $loadChilds && $this->_document->documentElement != null ) {				
				$this->_loadHtmlWidgets($this->_document->documentElement);
				return true;
			}
		}			

		return false;
    }
    private function _loadHtmlWidgets($rootNode) {
    	foreach ($rootNode->childNodes as $node) {
		    if ($node->nodeType == XML_ELEMENT_NODE) {
		    	$elementName = trim($node->getAttribute('name'));
				$newWidget = $this->_getWidgetInstance($node, $elementName);
	    		if( $newWidget != null ) {
	    			$newWidget->_node = $node;
	    			$this->_widget->addElement($elementName, $newWidget);
	    		}

	    		if( $newWidget == null
	    			|| $newWidget instanceof EWebby_UI_Widgets_HtmlWidget ) {
		    		$this->_loadHtmlWidgets($node);
	    		}
		    }
		}
    }
    private function _getWidgetInstance($node, $elementName) {
    	$newWidget = null;
    	if( strtolower($node->nodeName) == EWebby_UI_Widgets_Widget::WIDGETTAG ) {
    		$widgetClass = $node->getAttribute('type');
    		if( !$widgetClass ) {
    			throw new EWebby_Exception('the widget [' . $elementName . '] has no type');
    		}
    		$newWidget = new $widgetClass();
    		if( $elementName == '' ) {
    			$elementName = $newWidget->getHashKey();
    		}
    	} else {
    		if( $elementName != '' ) {
    			$newWidget = new EWebby_UI_Widgets_HtmlWidget($node->nodeName);
    		}	    			
    	}
    	
    	return $newWidget;
    }
    
    public function appendNewNode($content='') {
    	$newNode = $this->_document->createCDATASection($content);
    	$this->_document->appendChild($newNode);
    	
    	return $newNode;
    }
    
    public function queryDocument($xQuery) {
		$xpath = new DOMXPath( $this->_document );

		return $xpath->query($xQuery);
    }
    
    public function replaceWidgetContentWith($text) {
    	$nodes = $this->_document->getElementsByTagName(EWebby_UI_Widgets_Widget::WIDGETCONTENTTAG);
		if( $nodes->length > 0 ) {
    		$nodes->item(0)->parentNode->replaceChild(
   				$nodes->item(0)->ownerDocument->createCDATASection($text),
   				$nodes->item(0));
			
   			return true;
		}
		
		return false;
    }
    
    public function getContent() {
    	$output = $this->_document->saveHTML();
    	if( $this->_widget != null 
    		&& !($this->_widget instanceof EWebby_UI_Page) ) {
			$output = preg_replace('/^<!DOCTYPE.+?>/', '',
				str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $output));    		
    	}

    	return $output;
    }
}